/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package at.nhmwien.schema_mapping_tool.schemaReaders;

import java.util.*;
import java.io.*;

import com.sun.xml.xsom.parser.XSOMParser;
import com.sun.xml.xsom.XSSchemaSet;
import com.sun.xml.xsom.XSElementDecl;
import com.sun.xml.xsom.XSType;
import com.sun.xml.xsom.*;

/**
 *
 * @author wkoller
 */
public class XsdXSOMConverter extends FileConverter {
    private int callStackNumber = 0;

    public LinkedHashMap<String,LinkedHashMap> parseFile( InputStream inputFile ) {
        LinkedHashMap<String,LinkedHashMap> fields = new LinkedHashMap<String, LinkedHashMap>();

        try {
            XSOMParser parser = new XSOMParser();

            parser.parse(inputFile);

            XSSchemaSet set = parser.getResult();

            LinkedHashMap<String,LinkedHashMap> elementField = null;
            Iterator<XSElementDecl> jtr = set.iterateElementDecls();
            while( jtr.hasNext() ) {
                XSElementDecl ele = jtr.next();

                elementField = this.parseElement(ele);

                // Check if we have an element
                if( elementField.entrySet().iterator().hasNext() ) {
                    Map.Entry<String,LinkedHashMap> elementFieldInfo = elementField.entrySet().iterator().next();
                    if( elementFieldInfo != null ) {
                        fields.put(elementFieldInfo.getKey(), elementFieldInfo.getValue() );
                    }
                }
            }
        }
        catch( Exception e ) {
            e.printStackTrace();
        }

        return fields;
    }

    public LinkedHashMap<String,LinkedHashMap> parseParticle( XSParticle particle ) {
        XSTerm complTerm = particle.getTerm();
        LinkedHashMap<String,LinkedHashMap> fields = new LinkedHashMap<String, LinkedHashMap>();

        if( complTerm.isModelGroup() ) {
            XSModelGroup complModelGroup = complTerm.asModelGroup();
            XSParticle[] complChildren = complModelGroup.getChildren();

            LinkedHashMap<String,LinkedHashMap> elementField = null;
            for( int i = 0; i < complChildren.length; i++ ) {
                elementField = this.parseParticle( complChildren[i] );

                // Check if we have an element
                Iterator<Map.Entry<String, LinkedHashMap>> elementIt = elementField.entrySet().iterator();

                while( elementIt.hasNext() ) {
                    Map.Entry<String,LinkedHashMap> elementFieldInfo = elementIt.next();
                    fields.put(elementFieldInfo.getKey(), elementFieldInfo.getValue() );
                }

                /*if( elementField.entrySet().iterator().hasNext() ) {
                    Map.Entry<String,LinkedHashMap> elementFieldInfo = elementField.entrySet().iterator().next();
                }*/
            }
        }
        else if( complTerm.isModelGroupDecl() ) {
            XSModelGroupDecl complModelGroupDecl = complTerm.asModelGroupDecl();
            XSParticle[] complChildren = complModelGroupDecl.getModelGroup().getChildren();

            LinkedHashMap<String,LinkedHashMap> elementField = null;
            for( int i = 0; i < complChildren.length; i++ ) {
                elementField = this.parseParticle( complChildren[i] );

                // Check if we have an element
                if( elementField.entrySet().iterator().hasNext() ) {
                    Map.Entry<String,LinkedHashMap> elementFieldInfo = elementField.entrySet().iterator().next();
                    fields.put(elementFieldInfo.getKey(), elementFieldInfo.getValue() );
                }
            }
        }
        else if( complTerm.isElementDecl() ) {
            fields = this.parseElement( complTerm.asElementDecl() );
        }

        return fields;
    }

    public LinkedHashMap<String,LinkedHashMap> parseElement( XSElementDecl element ) {
        callStackNumber++;

        XSType eleType = element.getType();
        
        LinkedHashMap<String,LinkedHashMap> subFields = null;

        //System.out.println( "DEBUG (" + callStackNumber + "): Element '" + element.getName() + "' / '" + eleType.getName() + "'" );

        if( eleType.isComplexType() ) {
            XSComplexType complType = eleType.asComplexType();
            XSContentType complContent = complType.getContentType();
            XSParticle complParticle = complContent.asParticle();
            if( complParticle != null ) {
                subFields = this.parseParticle(complParticle);
            }
        }

        LinkedHashMap fieldInfo = new LinkedHashMap();
        fieldInfo.put( "name", element.getName() );
        fieldInfo.put( "subfields", subFields );

        LinkedHashMap<String,LinkedHashMap> fields = new LinkedHashMap<String, LinkedHashMap>();
        fields.put( element.getName(), fieldInfo);
        /*else if( eleType.isSimpleType() ) {
            XSSimpleType simplType = eleType.asSimpleType();

            if( simplType.isRestriction() ) {
                XSRestrictionSimpleType restSimplType = simplType.asRestriction();
            }
        }*/

        callStackNumber--;

        return fields;
    }
}
